#ifndef THINK_THINK_PROCESS_PIPES_UNIX_H
#define THINK_THINK_PROCESS_PIPES_UNIX_H

static char* think_process_pipes_unix =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: yunwuxin <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think\\process\\pipes;\n"
	"\n"
	"use think\\Process;\n"
	"\n"
	"class Unix extends Pipes\n"
	"{\n"
	"\n"
	"    /** @var bool */\n"
	"    private $ttyMode;\n"
	"    /** @var bool */\n"
	"    private $ptyMode;\n"
	"    /** @var bool */\n"
	"    private $disableOutput;\n"
	"\n"
	"    public function __construct($ttyMode, $ptyMode, $input, $disableOutput)\n"
	"    {\n"
	"        $this->ttyMode       = (bool) $ttyMode;\n"
	"        $this->ptyMode       = (bool) $ptyMode;\n"
	"        $this->disableOutput = (bool) $disableOutput;\n"
	"\n"
	"        if (is_resource($input)) {\n"
	"            $this->input = $input;\n"
	"        } else {\n"
	"            $this->inputBuffer = (string) $input;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    public function __destruct()\n"
	"    {\n"
	"        $this->close();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function getDescriptors()\n"
	"    {\n"
	"        if ($this->disableOutput) {\n"
	"            $nullstream = fopen(\'/dev/null\', \'c\');\n"
	"\n"
	"            return [\n"
	"                [\'pipe\', \'r\'],\n"
	"                $nullstream,\n"
	"                $nullstream,\n"
	"            ];\n"
	"        }\n"
	"\n"
	"        if ($this->ttyMode) {\n"
	"            return [\n"
	"                [\'file\', \'/dev/tty\', \'r\'],\n"
	"                [\'file\', \'/dev/tty\', \'w\'],\n"
	"                [\'file\', \'/dev/tty\', \'w\'],\n"
	"            ];\n"
	"        }\n"
	"\n"
	"        if ($this->ptyMode && Process::isPtySupported()) {\n"
	"            return [\n"
	"                [\'pty\'],\n"
	"                [\'pty\'],\n"
	"                [\'pty\'],\n"
	"            ];\n"
	"        }\n"
	"\n"
	"        return [\n"
	"            [\'pipe\', \'r\'],\n"
	"            [\'pipe\', \'w\'], // stdout\n"
	"            [\'pipe\', \'w\'], // stderr\n"
	"        ];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function getFiles()\n"
	"    {\n"
	"        return [];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function readAndWrite($blocking, $close = false)\n"
	"    {\n"
	"\n"
	"        if (1 === count($this->pipes) && [0] === array_keys($this->pipes)) {\n"
	"            fclose($this->pipes[0]);\n"
	"            unset($this->pipes[0]);\n"
	"        }\n"
	"\n"
	"        if (empty($this->pipes)) {\n"
	"            return [];\n"
	"        }\n"
	"\n"
	"        $this->unblock();\n"
	"\n"
	"        $read = [];\n"
	"\n"
	"        if (null !== $this->input) {\n"
	"            $r = array_merge($this->pipes, [\'input\' => $this->input]);\n"
	"        } else {\n"
	"            $r = $this->pipes;\n"
	"        }\n"
	"\n"
	"        unset($r[0]);\n"
	"\n"
	"        $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null;\n"
	"        $e = null;\n"
	"\n"
	"        if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {\n"
	"\n"
	"            if (!$this->hasSystemCallBeenInterrupted()) {\n"
	"                $this->pipes = [];\n"
	"            }\n"
	"\n"
	"            return $read;\n"
	"        }\n"
	"\n"
	"        if (0 === $n) {\n"
	"            return $read;\n"
	"        }\n"
	"\n"
	"        foreach ($r as $pipe) {\n"
	"\n"
	"            $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : \'input\';\n"
	"            $data = \'\';\n"
	"            while (\'\' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) {\n"
	"                $data .= $dataread;\n"
	"            }\n"
	"\n"
	"            if (\'\' !== $data) {\n"
	"                if (\'input\' === $type) {\n"
	"                    $this->inputBuffer .= $data;\n"
	"                } else {\n"
	"                    $read[$type] = $data;\n"
	"                }\n"
	"            }\n"
	"\n"
	"            if (false === $data || (true === $close && feof($pipe) && \'\' === $data)) {\n"
	"                if (\'input\' === $type) {\n"
	"                    $this->input = null;\n"
	"                } else {\n"
	"                    fclose($this->pipes[$type]);\n"
	"                    unset($this->pipes[$type]);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (null !== $w && 0 < count($w)) {\n"
	"            while (strlen($this->inputBuffer)) {\n"
	"                $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k\n"
	"                if ($written > 0) {\n"
	"                    $this->inputBuffer = (string) substr($this->inputBuffer, $written);\n"
	"                } else {\n"
	"                    break;\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (\'\' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) {\n"
	"            fclose($this->pipes[0]);\n"
	"            unset($this->pipes[0]);\n"
	"        }\n"
	"\n"
	"        return $read;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function areOpen()\n"
	"    {\n"
	"        return (bool) $this->pipes;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 创建一个新的 UnixPipes 实例\n"
	"     * @param Process         $process\n"
	"     * @param string|resource $input\n"
	"     * @return self\n"
	"     */\n"
	"    public static function create(Process $process, $input)\n"
	"    {\n"
	"        return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled());\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif